// -------- 普通函数 ---------
function test(value: string): string {   // 函数定义
    console.log("调用函数" + value)
    return "返回函数"
}

// ------- 匿名函数 ---------
// 写法一
const hello1 = function (txt: string) {
    console.log('hello ' + txt);
}

// 写法二  
const hello2: (txt: string) => string = function (txt):string {
    console.log('hello ' + txt);
    return "demo"
};

// -------- 构造函数 --------
// 结构 var res = new Function ([arg1[, arg2[, ...argN]],] functionBody)
var myFunction = new Function("a", "b", "return a * b"); 

// ------- 传参 ------
// 可选参数
function buildName(firstName: string, lastName?: string) {
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}

// 默认传参
// 注：可选传参和默认传参同时出现时，如果参数位置靠后的参数要赋值，则位置靠前的参数也必须赋值。
function defaultParams(firstName: string, age?:number, lastName: string = "shengqi") {
    return "defaultParams:" + firstName + " " + lastName + "  age:" + age
}

//剩余参数
// 剩余参数要位于参数集末尾
function joinNumbers(header:string, ...nums:number[]) {
    
    let numsStr = header +  " nums长度：" + nums.length + "  "
    nums.every((val, index, array) => {
        numsStr += val + " "
        return true //返回true表示继续执行循环，直到达到数组边界
    })

    console.log("剩余参数，参数:" + numsStr)
}

test("funcation")              // 调用函数
hello1("caller1")
console.log("不传可选参数：" + buildName("wu"))
console.log("带可选参数：" + buildName("wu", "shengqi"))
console.log(defaultParams("wu", 18, "shengqi1"))
console.log(defaultParams("wu", 18))
joinNumbers("非剩余参数",1, 2, 3, 4, 5)
console.log("构造函数：" + myFunction(2,3))